<script>
  // 对整数的二进制表示取反（0 变 1 ，1 变 0）后，再转换为十进制表示，可以得到这个整数的补数
  // 例如，整数 5 的二进制表示是 "101" ，取反后得到 "010" ，再转回十进制表示得到补数 2 。
  // 给你一个整数 num ，输出它的补数
  // 来源：力扣（LeetCode）
  // 链接：https://leetcode.cn/problems/number-complement

  //  示例 1：

  // 输入：num = 5
  // 输出：2
  // 解释：5 的二进制表示为 101（没有前导零位），其补数为 010。所以你需要输出 2 。
  // 示例 2：

  // 输入：num = 1
  // 输出：0
  // 解释：1 的二进制表示为 1（没有前导零位），其补数为 0。所以你需要输出 0 。

  //   &	AND	如果两位都是 1 则设置每位为 1
  //   |	OR	如果两位之一为 1 则设置每位为 1
  //   ^	XOR	如果两位只有一位为 1 则设置每位为 1
  //   ~	NOT	反转所有位
  //   <<	零填充左位移	通过从右推入零向左位移，并使最左边的位脱落。
  //   >>	有符号右位移	通过从左推入最左位的拷贝来向右位移，并使最右边的位脱落。
  //   >>>	零填充右位移	通过从左推入零来向右位移，并使最右边的位脱落。

  //   5 & 1	1	0101 & 0001	0001
  //   5 | 1	5	0101 | 0001	0101
  //   5 ^ 1	4	0101 ^ 0001	0100
  //   ~ 5	10	~0101	1010
  //   5 << 1	10	0101 << 1	1010
  //   5 >> 1	2	0101 >> 1	0010
  //   5 >>> 1	2	0101 >>> 1	0010

  /**
   * 101  补数 010  为 2
   * 那么 我要拿到 111 
   * 进行 111 ^ 101 就可以拿到 010
   */

  /**
   * @param {number} num
   * @return {number}
   */
  var findComplement = function (num) {
    if (num == 1) return 0;
    var k = 0;
    var tmp = num;
    while (num) {
      num >>= 1;
      k <<= 1;
      k |= 1;
    }

    return tmp ^ k;
  };
</script>
